//
// Created by DIRICHLET on 2022/4/10.
//




#include "TcpClient.h"
#include "htime.h"
#include "MessageFrame.h"
#include "UdpClient.h"
#include "third/cmdline.h"
#include "UdpServer.h"

using namespace hv;
//hv一个客户端 两个逻辑
//other 一个服务端 仅接受并解码
const int MAX_BUFFER_SIZE=3000;
void Decode_Receive(char *recveive_buf)
{
    asn_dec_rval_t rval;
    MessageFrame_t *rectangle = (MessageFrame_t *)calloc(1, sizeof(MessageFrame_t));
    // UPER 解码
    asn_codec_ctx_t *opt_codec_ctx = 0;
    rval = uper_decode(opt_codec_ctx, &asn_DEF_MessageFrame, (void **) &rectangle,
                       recveive_buf, MAX_BUFFER_SIZE, 0, 0);//size  is maxinum buffer  size
    if (rval.code == RC_OK) {
        printf("\n ----- decode ASN success-----\n");
    } else {
        printf("\n ----- decode ASN failed ------\n");
        exit(1);
    }

    // printf the msg
    xer_fprint(stdout, &asn_DEF_MessageFrame, rectangle);

    // 执行其他业务
}

void initUdpClient(int port,int toport){

    UdpClient* cli=new UdpClient ;
    UdpClient *nextCli=new UdpClient ;
    int sockfd = cli->createsocket(port);
    if (sockfd < 0) {
        throw("Client can't bind port");
    }
    int tosockfd = nextCli->createsocket(toport);
    if (tosockfd < 0) {
        throw("ClientNext can't bind port");
    }

    printf("client sendto port %d, sockfd=%d ...\n", port, sockfd);



    cli->onMessage = [nextCli](const SocketChannelPtr& channel, Buffer* buf) {
        printf("< getdata\n");
        Decode_Receive((char*)buf->data());
        nextCli->sendto((char*)buf->data(),(int)buf->size());
        //printf("< %.*s\n", (int)buf->size(), (char*)buf->data());
    };
    nextCli->start();
    cli->start();
    cli->sendto("getdata");

    // sendto(time) every 3s
//    cli.loop()->setInterval(3000, [&cli](TimerID timerID) {
//        char str[DATETIME_FMT_BUFLEN] = {0};
//        datetime_t dt = datetime_now();
//        datetime_fmt(&dt, str);
//        cli.sendto(str);
//    });
    //cli.sendto(str);

}


void initUdpServer(int port){
    UdpServer* srv=new UdpServer ;
    //srv->loop()
    int bindfd = srv->createsocket(port);
    if (bindfd < 0) {
        throw("Server can't bind port");
    }
    printf("server bind on port %d, bindfd=%d ...\n", port, bindfd);
    srv->onMessage = [](const SocketChannelPtr& channel, Buffer* buf) {
        // echo
        printf("< getdata\n");
        Decode_Receive((char*)buf->data());
        //channel->write(buf);
    };
    srv->start();
    //char  s[]="hello,world";

};

int main(int argc, char* argv[]) {
    cmdline::parser cmd;
    cmd.add<int>("portS", '\0', "self port number,server mod", false);
    cmd.add<int>("portCL",'\0',"last  port in client, client mod", false);
    cmd.add<int>("portCN",'\0',"next  port in client, client mod", false);

    cmd.parse_check(argc, argv);

    //int toPort=-1;
   if(cmd.exist("portS")){
       initUdpServer(cmd.get<int>("portS"));
   } else if(cmd.exist("portCL")&&cmd.exist("portCN")){
       initUdpClient(cmd.get<int>("portCL"),cmd.get<int>("portCN"));
   }
   else{
       printf("mod match error\n");
       return -100;
   }









    // press Enter to stop
    while (getchar() != '\n');

    return 0;
}
